#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <sys/types.h>  
#include <sys/wait.h>  
#include <unistd.h>  
#include <signal.h>  

#define MAXARGS  20    // 最大参数数量  
#define ARGLEN   100   // 每个参数的最大长度  

/**  
 * 从输入缓冲区创建一个新的字符串，移除末尾的换行符并分配内存  
 * @param buf 输入缓冲区  
 * @return 新分配的字符串  
 */  
char *makestring(char *buf) {  
    size_t len = strlen(buf);  
    if (len > 0 && buf[len - 1] == '\n') {  
        buf[len - 1] = '\0';        // 移除换行符  
    }  
    char *cp = malloc(len + 1);      // 分配内存  
    if (cp == NULL) {                // 检查内存分配是否成功  
        fprintf(stderr, "no memory\n");  
        exit(1);  
    }  
    strcpy(cp, buf);                 // 拷贝字符串  
    return cp;                       // 返回新字符串  
}  

/**  
 * 执行命令  
 * @param arglist 参数列表  
 */  
void execute(char *arglist[]) {  
    pid_t pid;  
    int exitstatus;  

    pid = fork();                     // 创建子进程  
    if (pid == -1) {  
        perror("fork failed");  
        exit(1);  
    } else if (pid == 0) {  
        // 子进程：执行命令  
        execvp(arglist[0], arglist);  
        // execvp失败，输出错误信息并退出  
        perror("execvp failed");  
        exit(1);  
    } else {  
        // 父进程：等待子进程结束  
        if (waitpid(pid, &exitstatus, 0) == -1) {  
            perror("waitpid failed");  
            return;  
        }  

        // 使用标准宏解析退出状态  
        if (WIFEXITED(exitstatus)) {  
            printf("child exited with status %d\n", WEXITSTATUS(exitstatus));  
        } else if (WIFSIGNALED(exitstatus)) {  
            printf("child terminated by signal %d\n", WTERMSIG(exitstatus));  
        } else {  
            printf("child exited with unexpected status %d\n", exitstatus);  
        }  
    }  
}  

int main() {  
    char *arglist[MAXARGS + 1];      // 参数列表，最后一个元素为NULL  
    int numargs = 0;                  // 当前参数数量  
    char argbuf[ARGLEN];              // 输入缓冲区  

    while (1) {                        // 持续循环，直到用户退出  
        printf("Arg[%d]? ", numargs);  
        if (fgets(argbuf, ARGLEN, stdin)) {  
            // 移除换行符并检查输入是否为空  
            size_t len = strlen(argbuf);  
            if (len > 0 && argbuf[len - 1] == '\n') {  
                argbuf[len - 1] = '\0';  
            }  

            if (argbuf[0] != '\0') {  
                if (numargs < MAXARGS) {  
                    arglist[numargs++] = makestring(argbuf);  
                } else {  
                    fprintf(stderr, "Maximum number of arguments (%d) reached.\n", MAXARGS);  
                }  
            } else {  
                if (numargs > 0) {  
                    arglist[numargs] = NULL;   // 参数列表末尾设置为NULL  
                    execute(arglist);          // 执行命令  
                    // 释放分配的内存  
                    for (int i = 0; i < numargs; i++) {  
                        free(arglist[i]);  
                    }  
                    numargs = 0;               // 重置参数计数  
                } else {  
                    // 用户输入空行且无参数，退出程序  
                    break;  
                }  
            }  
        } else {  
            // 读取输入失败（例如EOF），退出循环  
            break;  
        }  
    }  

    return 0;  
}
